#include "chipFrame.h"
#include "chipFrame.h"
#include "common.h"
#include <wx/dir.h>
#include "thread.h"

#include "icons/next.xpm"
#include "icons/random_off.xpm"
#include "icons/random_on.xpm"
#include "icons/play.xpm"
#include "icons/pause.xpm"
#include "icons/prev.xpm"


//(*InternalHeaders(chipFrame)
#include <wx/artprov.h>
#include <wx/bitmap.h>
#include <wx/font.h>
#include <wx/intl.h>
#include <wx/image.h>
#include <wx/string.h>
//*)

//(*IdInit(chipFrame)
const long chipFrame::ID_BITMAPBUTTON3 = wxNewId();
const long chipFrame::ID_SLIDER1 = wxNewId();
const long chipFrame::ID_STATICTEXT2 = wxNewId();
const long chipFrame::ID_STATICTEXD = wxNewId();
const long chipFrame::ID_LISTCTRL1 = wxNewId();
const long chipFrame::ID_BITMAPBUTTON1 = wxNewId();
const long chipFrame::ID_BITMAPBUTTON2 = wxNewId();
const long chipFrame::ID_BITMAPBUTTON4 = wxNewId();
const long chipFrame::ID_PANEL1 = wxNewId();
const long chipFrame::ID_TIMER1 = wxNewId();
//*)

BEGIN_EVENT_TABLE(chipFrame,wxFrame)
	EVT_TIMER(ID_TIMER1, chipFrame::timerEvent)
	EVT_MENU(chip_AddFiles, chipFrame::openFiles)
	EVT_MENU(chip_AddDir, chipFrame::openFiles)
	EVT_MENU(chip_SaveList, chipFrame::openFiles)
	EVT_BUTTON    (ID_BITMAPBUTTON1, chipFrame::playPrev)
	EVT_BUTTON    (ID_BITMAPBUTTON2, chipFrame::playNext)
//	EVT_COMMAND_SCROLL(ID_SLIDER1, chipFrame::sliderChange)

END_EVENT_TABLE()

bool endSong(void* arg) {
	return 0;
}

wxString filenameSession(_T(".currentsession"));
wxString aychipIdentifer(_T("#aychip current session generated on exit"));
wxString currSongz(_T("#current song number"));
wxString currSongPozition(_T("#current song position"));
wxString lastFilez(_T("#last files list"));

chipFrame::chipFrame(wxWindow* parent,wxWindowID id,const wxPoint& pos,const wxSize& size) {
	//(*Initialize(chipFrame)
	Create(parent, wxID_ANY, _("aychip player v .03alfa"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
	SetClientSize(wxSize(562,318));
	SetFocus();
	wxFont thisFont(9,wxMODERN,wxFONTSTYLE_NORMAL,wxNORMAL,false,wxEmptyString,wxFONTENCODING_DEFAULT);
	SetFont(thisFont);
	{
	wxIcon FrameIcon;
	FrameIcon.CopyFromBitmap(wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(_T("wxART_GO_HOME")),wxART_MENU));
	SetIcon(FrameIcon);
	}
	Panel1 = new wxPanel(this, ID_PANEL1, wxPoint(8,40), wxDLG_UNIT(this,wxSize(321,170)), wxTAB_TRAVERSAL, _T("ID_PANEL1"));
	playButton = new wxBitmapButton(Panel1, ID_BITMAPBUTTON3, wxNullBitmap, wxPoint(48,256), wxSize(32,32), wxBU_AUTODRAW, wxDefaultValidator, _T("ID_BITMAPBUTTON3"));
	playButton->SetDefault();
	playButton->SetToolTip(_("play / pause"));
	slider = new wxSlider(Panel1, ID_SLIDER1, 0, 0, 100, wxPoint(128,256), wxSize(336,16), 0, wxDefaultValidator, _T("ID_SLIDER1"));
	slider->SetForegroundColour(wxColour(0,45,255));
	curPlayingTitle = new wxStaticText(Panel1, ID_STATICTEXT2, _("no module"), wxPoint(128,272), wxSize(376,15), wxST_NO_AUTORESIZE, _T("ID_STATICTEXT2"));
	wxFont curPlayingTitleFont(8,wxSWISS,wxFONTSTYLE_NORMAL,wxNORMAL,false,wxEmptyString,wxFONTENCODING_DEFAULT);
	curPlayingTitle->SetFont(curPlayingTitleFont);
	curPlayingTime = new wxStaticText(Panel1, ID_STATICTEXD, _("00:00/00:00"), wxPoint(472,256), wxSize(80,16), 0, _T("ID_STATICTEXD"));
	ListCtrl1 = new wxListCtrl(Panel1, ID_LISTCTRL1, wxPoint(8,8), wxSize(544,240), wxLC_REPORT|wxLC_SINGLE_SEL, wxDefaultValidator, _T("ID_LISTCTRL1"));
	wxFont ListCtrl1Font(9,wxSWISS,wxFONTSTYLE_NORMAL,wxNORMAL,false,wxEmptyString,wxFONTENCODING_DEFAULT);
	ListCtrl1->SetFont(ListCtrl1Font);
	chipStop = new wxBitmapButton(Panel1, ID_BITMAPBUTTON1, wxNullBitmap, wxPoint(8,256), wxSize(32,32), wxBU_AUTODRAW, wxDefaultValidator, _T("ID_BITMAPBUTTON1"));
	chipStop->SetDefault();
	chipStop->SetToolTip(_("prev track"));
	BitmapButton1 = new wxBitmapButton(Panel1, ID_BITMAPBUTTON2, wxNullBitmap, wxPoint(88,256), wxSize(32,32), wxBU_AUTODRAW, wxDefaultValidator, _T("ID_BITMAPBUTTON2"));
	BitmapButton1->SetToolTip(_("next track"));
	BitmapButton3 = new wxBitmapButton(Panel1, ID_BITMAPBUTTON4, wxNullBitmap, wxPoint(512,272), wxSize(40,16), wxBU_AUTODRAW, wxDefaultValidator, _T("ID_BITMAPBUTTON4"));
	timer.SetOwner(this, ID_TIMER1);
	timer.Start(100, false);
	dirDialog = new wxDirDialog(this, _("Select directory"), wxEmptyString, wxDD_DEFAULT_STYLE, wxDefaultPosition, wxDefaultSize, _T("wxDirDialog"));
	menu = new wxMenuBar();
	SetMenuBar(menu);
	fileDialog = new wxFileDialog(this, _("Select file"), wxEmptyString, wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN|wxFD_FILE_MUST_EXIST|wxFD_MULTIPLE, wxDefaultPosition, wxDefaultSize, _T("wxFileDialog"));
	saveListDialog = new wxFileDialog(this, _("Save chip playlist"), wxEmptyString, _("list.chip"), wxFileSelectorDefaultWildcardStr, wxFD_SAVE, wxDefaultPosition, wxDefaultSize, _T("wxFileDialog"));
	Center();

	Connect(ID_BITMAPBUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&chipFrame::OnplayButtonClick);
	Connect(ID_LISTCTRL1,wxEVT_COMMAND_LIST_ITEM_ACTIVATED,(wxObjectEventFunction)&chipFrame::playTrack);
	Connect(ID_BITMAPBUTTON4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&chipFrame::OnBitmapButton3Click);
	Connect(wxID_ANY,wxEVT_CLOSE_WINDOW,(wxObjectEventFunction)&chipFrame::OnClose);
	//*)

#define iconSize 16

	wxBitmap newImage(prev_xpm);
	chipStop->SetBitmapHover(newImage);
	chipStop->SetBitmapFocus(newImage);
	chipStop->SetBitmapDisabled(newImage);
	chipStop->SetBitmapLabel(newImage);

	wxBitmap newImage1(next_xpm);
	BitmapButton1->SetBitmapHover(newImage1);
	BitmapButton1->SetBitmapFocus(newImage1);
	BitmapButton1->SetBitmapDisabled(newImage1);
	BitmapButton1->SetBitmapLabel(newImage1);

	wxBitmap newImage2(random_on_xpm);
	BitmapButton3->SetBitmapHover(newImage2);
	BitmapButton3->SetBitmapFocus(newImage2);
	BitmapButton3->SetBitmapDisabled(newImage2);
	BitmapButton3->SetBitmapLabel(newImage2);

	taskIcon = new wxTaskBarIcon();
	wxIcon* myIcon = new wxIcon();
	ListCtrl1->InsertColumn(0, wxT("title / author"), wxLIST_FORMAT_LEFT);
	ListCtrl1->SetColumnWidth(0, 430);
//	ListCtrl1->InsertColumn(1, wxT("author"), wxLIST_FORMAT_CENTER);
//	ListCtrl1->SetColumnWidth(1, 200);
	ListCtrl1->InsertColumn(1, wxT("time"), wxLIST_FORMAT_CENTER);
	ListCtrl1->SetColumnWidth(2, 20);
	Connect(chip_NextTrack, listBoxEvent, wxCommandEventHandler(chipFrame::listBoxEvents));
	Connect(chip_CallbackFunction, myEvent, wxCommandEventHandler(chipFrame::playNext));

	wxMenu *plmenu = new wxMenu(0);
    plmenu->Append(chip_AddFiles, wxString::FromAscii("  add files  "));
	plmenu->Append(chip_AddDir, wxString::FromAscii("  add dir  "));
	plmenu->Append(chip_SaveList, wxString::FromAscii("  save list  "));
	menu->Append(plmenu, wxString::FromAscii(" playlist "));
/*
	wxMenu *abmenu = new wxMenu(0);
	abmenu->Append(99999, wxString::FromAscii(" mode > "));
	abmenu->Append(99998, wxString::FromAscii(" convert to ogg > "));
	menu->Append(abmenu, wxString::FromAscii(" tools "));
*/

    playlists.push_back(new PlayList());

    player = new Player();
    player->playList = playlists[0];
//	player->playList->open(wxString::FromAscii("list.chip"));	/// todo save in registry :)

	/// if old session end correctly - try to open old sess

}

chipFrame::~chipFrame()
{
	//(*Destroy(chipFrame)
	//*)

}

void chipFrame::playNext(wxCommandEvent& event) {
    player->playNext();
    setPlayIcon();
}
void chipFrame::playPrev(wxCommandEvent& event) {
    player->playPrev();
    setPlayIcon();
}

void chipFrame::setPlayIcon() {
	wxBitmap* newImage;
	if (!player->currentSong) {
		newImage = new wxBitmap(play_xpm);
	} else {
		if (ay_songstarted(player->currentSong)) {
			newImage = new wxBitmap(pause_xpm);
		}
	}
	playButton->SetBitmapHover(*newImage);
	playButton->SetBitmapFocus(*newImage);
	playButton->SetBitmapDisabled(*newImage);
	playButton->SetBitmapLabel(*newImage);
	delete newImage;
}


void chipFrame::openFiles(wxCommandEvent &event) {
	switch (event.GetId() ) {
		case chip_AddFiles:
			if (wxID_OK ==fileDialog->ShowModal()) {
				wxArrayString path;
				fileDialog->GetPaths(path);
				addFilesToCurrentPlayList(path);
			}
			break;
		case chip_AddDir:
			if (wxID_OK == dirDialog->ShowModal()) {
			    wxArrayString* path = new wxArrayString;
			    wxDir dir(dirDialog->GetPath());
			    if (dir.IsOpened()) {
					dir.GetAllFiles(dirDialog->GetPath(), path);
///					wxArrayString paths = *path;
					addFilesToCurrentPlayList(*path, 0);
			    }
                delete path;
			}
			break;
		case chip_SaveList:
			if (wxID_OK == saveListDialog->ShowModal()){
				saveList(saveListDialog->GetPath());
			}
		default:
			break;
	}

}

void chipFrame::playTrack(wxListEvent& event) {
	PlayList *curr = playlists[0];
	player->play(curr, event.GetIndex(), true);	/// true - do not use random id dbl clkc:)
	printf("double click-click! item %d\n", event.GetIndex());

	setPlayIcon();
}

void chipFrame::addToList(PlayList* curr, PlayListItem *item) {
	long itemIndex = ListCtrl1->InsertItem(curr->getListSize(), item->displayInfo);
	ListCtrl1->SetItem(itemIndex, 1, item->durationStr);
}

void chipFrame::addFilesToCurrentPlayListFast(wxArrayString paths) {
	PlayList* curr = playlists[0];
	long length; wxString str, str2;
	int i = 0;
	while( i < paths.GetCount()) {
		str = paths[i++];
		paths[i++].ToLong(&length);	/// todo try except ?
		str2 = paths[i++];
		PlayListItem *item = curr->addItemFast(str, str2, length);
		if (item) {
			addToList(curr, item);
		}
	}
}

void chipFrame::addFilesToCurrentPlayList(wxArrayString paths, int addHidden) {
    PlayList* curr = playlists[0];

	MyWorkerThread *thread = new MyWorkerThread(this);
	thread->Create(1024 * 1024 * 5);	/// thread stack 5 mb ???
	thread->Run();
    for (int i = 0; i < paths.GetCount(); i++) {
		if (wxNOT_FOUND == paths[i].Find(wxString::FromAscii(".chip"))) {
			if (!addHidden && wxNOT_FOUND != paths[i].Find(wxString::FromAscii("/."))) continue;
			PlayListItem *item = curr->addItem(paths[i]);
			if (item) {
				addToList(curr, item);
			}
    	} else {	/// its list file. test for list
    		wxTextFile readList(paths[i]);
    		readList.Open();
			wxString str = readList.GetLastLine(), str2;
			long length;
			if (!str.IsSameAs(listMarker) ) {	/// its our playlist!
				for(int i=1; i < readList.GetLineCount();) {
					str = readList.GetLine(i++);
					readList.GetLine(i++).ToLong(&length);	/// todo try except ?
					str2 = readList.GetLine(i++);
					PlayListItem *item = curr->addItemFast(str, str2, length);
					if (item) {
						addToList(curr, item);
					}
				}
			}
    	}
    }
}

void chipFrame::saveList(wxString path) {
	PlayList* curr = playlists[0];
	curr->save(path);
}
const char * siska = 0;

void chipFrame::timerEvent(wxTimerEvent& event) {
	static int a = 1;	/// for timer 100 msec

	if (player->currentSong) {
		char * iconData = new char [iconSize * 2];

		memset(iconData, 0, iconSize * 2);

		const unsigned char* regs = ay_getregs(player->currentSong);
		int cha = ( regs[0x08] & 0x0f ) ;
		int chb = ( regs[0x09] & 0x0f ) ;
		int chc = ( regs[0x0a] & 0x0f ) ;

	/// SET CHANNELs indicators ;)
		for(int i = 0x0f; i >= 0x00; i--) {
			if (chc > 0x0f - i) iconData[i*2 + 1] |= 0x78;
			if (chb > 0x0f - i) {
				iconData[i*2 + 1] |= 0x03;
				iconData[i*2] |= 0xc0;
			}
			if (cha > 0x0f - i) iconData[i*2] |= 0x1e;
		}
		wxBitmap iconko(iconData, iconSize, iconSize);
		wxIcon icon;
		icon.CopyFromBitmap(iconko);
		if (taskIcon) {
			taskIcon->SetIcon(icon, wxT("aychip")); ///)
		}
		delete iconData;

/// slider and label
		unsigned int elapsedTime = ay_getelapsedtime(player->currentSong);
		unsigned int duration = ay_getsonglength(player->currentSong);
		slider->SetValue(elapsedTime);
		if (a) {
			a--;
		} else {
			wxString time = wxString::Format(wxString::FromAscii("%02u:%02u/%02u:%02u"),\
				elapsedTime/ (50*60), elapsedTime/50 - 60*(elapsedTime/(50*60)),\
				duration/ (50*60), duration/50 - 60*(duration/(50*60)));
			curPlayingTime->SetLabel(time);
			a = 10;
		}
	}
}

void chipFrame::listBoxEvents(wxCommandEvent& event) {
	curPlayingTitle->SetLabel(player->playList->items[player->currentIndex]->displayInfo);
	slider->SetRange(0, player->playList->items[player->currentIndex]->duration);
	slider->SetValue(0);
}
/*
void chipFrame::sliderChange(wxScrollEvent& event) {
    int newPos = event.GetPosition();
}
*/

void chipFrame::OnBitmapButton3Click(wxCommandEvent& event)
{
	wxBitmap* newImage;
	if (player->random == chip_YES) {
		newImage = new wxBitmap(random_off_xpm);
		player->random = chip_NO;
	} else {
		newImage = new wxBitmap(random_on_xpm);
		player->random = chip_YES;
	}
	BitmapButton3->SetBitmapHover(*newImage);
	BitmapButton3->SetBitmapFocus(*newImage);
	BitmapButton3->SetBitmapDisabled(*newImage);
	BitmapButton3->SetBitmapLabel(*newImage);
	delete newImage;

///	wxIcon icon(_T("../icons/random_on.png"));
///	taskIcon->SetIcon(icon, (_T("supre")));

}

void chipFrame::OnplayButtonClick(wxCommandEvent& event)
{
	if (!player->currentSong) return;	/// no talk with me if you dont have muz!
	wxBitmap* newImage;
	if (ay_songstarted(player->currentSong)) {
		ay_stopsong(player->currentSong);
		newImage = new wxBitmap(play_xpm);
	} else {
		ay_startsong(player->currentSong);
		newImage = new wxBitmap(pause_xpm);
	}
	playButton->SetBitmapHover(*newImage);
	playButton->SetBitmapFocus(*newImage);
	playButton->SetBitmapDisabled(*newImage);
	playButton->SetBitmapLabel(*newImage);
	delete newImage;
/*	wxIcon icon; ///(_T("../icons/random_off.xpm"));
	icon.CopyFromBitmap(wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(_T("wxART_GO_HOME")),wxART_MENU));
  if (!taskIcon->SetIcon(icon, wxT("wxTaskBarIcon Sample")))
        MessageBox(0,(_T("Could not set icon.")),0,0);
*/
}


void chipFrame::OnClose(wxCloseEvent& event)
{
	/// save current state info
	delete taskIcon;
	taskIcon = 0;
	wxTextFile params;
	params.Create(filenameSession);

	params.AddLine(aychipIdentifer);
	if (player->currentSong) {
		params.AddLine(currSongz);
		params.AddLine(wxString::Format(_T("%d"),player->currentIndex));
		params.AddLine(currSongPozition);
		params.AddLine(wxString::Format(_T("%d"), ay_getelapsedtime(player->currentSong)));
	}
	params.AddLine(lastFilez);

	PLItem::iterator it = player->playList->items.begin();
	while(it!=player->playList->items.end()) {
		params.AddLine((*it)->path);
		params.AddLine(wxString::Format(_T("%d"), (*it)->duration));
		params.AddLine((*it++)->displayInfo);
	}
	params.Write();
	params.Close();

	Destroy();
}
